// A zigzag is accomplished by a sequence of console commands, and is
// activated by some bound key. The idea is that you rhythmically press
// your zigzag key as you run in order to get a speed up. This should
// be easier than the HyperOlympics style of pressing since one key press
// can substitute for several. However, you sacrifice a measure of control
// because the commands take a while to execute, and also the "wait"
// command is a coarser degree of control than you could manage yourself.
// I find I get a velocity of about 400 using my set-up. That's not
// a lot, but it is almost for free. 

// Quake must finish processing all current commands before it will
// accept any further commands, Those further commands might be player
// movement commands or attack (fire) commands. Since the zigzag
// necessarily takes some time to happen, the player is prevented from
// doing anything else whilst zigzagging. (Well, you can move the mouse
// to steer left and right or look up and down, but that's all. Any
// keyboard or mouse button inputs won't be processed until after the
// zigzag has finished.) So each zigzag key press incapacitates the
// player for the duration of the zigzag.

// Because of this, it seems sensible to keep the zigzag as short as is
// convenient for the player, and possibly to provide some visual or
// audio clues for when it is starting and stopping. You can see your
// movement wobbling, of course, but this isn't a particularly clear
// signal. So I included a facility to add other signals to the start
// and end of a zigzag.

alias zigzag_start "host_framerate 0.028";
 // Set host_framerate to something close to your usual framerate.
 // If you e.g. double this, you need to halve the sizes of delay1 and
 // delay2.
alias zigzag_end "host_framerate 0; play misc/talk.wav";
 // Reset host_framerate to normal. I also add a cue to show zigzagging
 // is ending.
 // I have a little sound, and then if nothing else needs doing I just
 // repeat the zigzag with another keypress every time I hear the sound.
 // This helped me with the rhythm of the thing. But you may prefer to
 // forget the "play" part.

alias delay1 "wait; wait";
alias delay2 "wait; wait";
 // These are two halves of the delay used in zigzagging. They don't
 // have to be equal.
 // What they are best set to depends on what host_framerate setting
 // you use. If you decide not to use host_framerate at all, this section
 // of the alias remains to give you some fine-tuning control over how
 // well zigzagging works.
 // In all cases, you'll want to experiment to find something that works
 // well for you.

// Since zigzagging to and fro may involve either strafing (if you are
// principally moving forward or back) or moving forward and back (if you
// are principally strafing) the zigzag is defined in terms of "to" and
// "fro" aliases which are reassigned depending on what movement the
// player is actually performing. So zigzagging should work whatever
// direction you happen to start moving in.

alias zig "zigzag_start; +to; delay2; -to; +fro; delay1";
 // the start of a zigzag.
 // We perform any cue specified here.
 // We move *to* one side, then *fro* back to the centre. -^-
alias zag__zig "delay2; -fro; +to; delay1; delay2; -to; +fro; delay1";
 // the middle, repeatable bit of a zigzag,
 // We move *fro* to the other side, then move *to* back to the first
 // side again, then *fro* back to the centre. -_-^-
alias zag "delay2; -fro; +to; delay1; -to; zigzag_end";
 // the end of a zigzag.
 // We move *fro* to the second side for a final time, and then go
 // back *to* the centre. -_-
 // Finally we perform any finishing cue specified.
alias zigzag  "zig;zag";
 // A single zigzag -^-_- is made of the zig bit and the zag bit.
alias zigzag2 "zig;zag__zig;zag";
 // A double zigzag -^-_-^-_- places a middle piece between the two ends.
alias zigzag3 "zig;zag__zig;zag__zig;zag";
 // A triple zigzag -^-_-^-_-^-_- is similar,
alias zigzag5 "zig;zag__zig;zag__zig;zag__zig;zag__zig;zag";
 // and a quintuple one -^-_-^-_-^-_-^-_-^-_- follows the same pattern.
 // You can extend as you desire.

alias do_zigzag zigzag2;
 // This is the action that pressing your zigzag key will actually perform.
 // I choose to do a double zigzag. But a single one may be better if you
 // can get into the quicker rhythm as the periods when you are out of
 // control will be shorter.
 // Use whichever alias you prefer. You could even dynamically change
 // this alias to select between different zigzags on the same key if
 // you so desire.

// I happen to use 'r' as my zigzag key: so it is unbound and bound below.
// Replace it with whichever control you would prefer to use to start a
// zigzag.

alias still  "unbind r;         alias setup_fwdback moving_fwdback; alias setup_strafe moving_strafe";
 // This is what happens when you are still and not moving.
 //  - the zigzag key is disabled, so if you press it you waste no time.
 //  - either sort of zigzagging is prepared for, since you might move
 //    sideways or forward/back.
alias moving "bind r do_zigzag; alias setup_fwdback;                alias setup_strafe";
 // This is what happens when you are moving.
 //  - the zigzag key is enabled.
 //  - other movements before you end this current one by releasing the
 //    key you have pressed are set to be ignored.

alias moving_fwdback "moving; alias +to +moveleft; alias -to -moveleft; alias +fro +moveright; alias -fro -moveright";
 // If you start by moving forward or back, the above movement setup is
 // performed, and to and fro are configured to be strafing.
alias moving_strafe  "moving; alias +to +forward;  alias -to -forward;  alias +fro +back;      alias -fro -back;     ";
 // If you start by strafing, the same movement setup is performed, but
 // this time to and fro are configured to be movements backwards
 // and forwards.

still;
 // We perform the still command to get the system ready - the player is
 // not moving right at the start.

// Now we define some new aliases that do the necessary bookkeeping
// for zigzagging as well as the usual movements.

alias +new_forward   "+forward;   moving_fwdback";
alias -new_forward   "still;            -forward";
alias +new_back      "+back;      moving_fwdback";
alias -new_back      "still;               -back";
alias +new_moveleft  "+moveleft;   moving_strafe";
alias -new_moveleft  "still;           -moveleft";
alias +new_moveright "+moveright;  moving_strafe";
alias -new_moveright "still;          -moveright";

// Finally you should reassign your movement keys to use the new_movements
// rather than the old ones. These are what I use but yours are no doubt
// very different, probably WSAD.

bind mouse2 +new_forward;
bind j      +new_back;
bind x      +new_moveleft;
bind space  +new_moveright;

// That's all!

// Thanks to Matthias Buecher for all his help in investigating aliases
// for zigzagging.


